package com.emar.adx.yiqifa.thread;

import com.emar.adx.yiqifa.util.HikariCPPoolUtil;
import com.emar.adx.yiqifa.util.RandomUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by xiaoliang
 * 2016.12.05 10:33
 *
 * @Version 1.0
 */
public class OracleDBBatchThread implements Runnable {
    public static final Logger logger = LoggerFactory.getLogger(OracleDBBatchThread.class);

    private Connection conn = null;
    private PreparedStatement pre = null;
    private Map<Integer,String> tableMap = new HashMap<Integer, String>();
    private int total = 100;
    private int index = 100;


    public void setTotal(int total) {
        this.total = total;
    }

    public OracleDBBatchThread(Map<Integer, String> tableMap, int index) {
        this.tableMap = tableMap;
        this.index = index;
    }

    @Override
    public void run() {
        int i = 0;
        while(i<total){
            batchInsert();
            logger.info(Thread.currentThread().getId() + " --> batch insert end , execute i = "+i);
            i ++;
        }
    }

    /**
     * 随机获取tablename
     * @return
     */
    private String getTableName(){
        int i = RandomUtil.random(0,index);
        return tableMap.get(i);
    }


    private String parseType(String oracleType){
        switch (oracleType){
            case "VARCHAR2": return "String";
            case "VARCHAR" : return "String";
            default: return "";
        }
    }

    public void batchInsert(){
        String tableName = this.getTableName();
        String columeSql = "select column_name,data_type,data_length from user_tab_columns where table_name= ? ";
        StringBuilder sb = new StringBuilder(1000);

        try {
            conn = HikariCPPoolUtil.getConnection();
            conn.setAutoCommit(false);

            pre = conn.prepareStatement(columeSql);
            pre.setString(1,tableName);

            Map<String,String> dataTypes = new HashMap<>();

            ResultSet res = pre.executeQuery();
            StringBuilder colums = new StringBuilder(500);
            StringBuilder params = new StringBuilder(500);
            int paramsNum = 0;
            int minLen = 40;

            if(res!=null){
                while (res.next()){
                    String columName = res.getString(1);
                    String columType = res.getString(2);
                    int dataLen = res.getInt(3);

                    String type = this.parseType(columType);
                    if(StringUtils.isBlank(type)){
                        continue;
                    }

                    dataTypes.put(columName,type);
                    colums.append(",").append(columName);
                    params.append(",").append("?");
                    paramsNum ++ ;
                    if(dataLen<minLen){
                        minLen = dataLen;
                    }
                }
                res.close();
            }

            sb.append("insert into ").append(tableName).append("(")
                    .append(colums.toString().replaceFirst(",",""))
                    .append(") values (")
                    .append(params.toString().replaceFirst(",",""))
                    .append(")");

            if(paramsNum>0){
                pre = conn.prepareStatement(sb.toString());
//                int nums = RandomUtil.random(10,1000);
                int nums = 1000;

                for(int k = 0;k<nums;k++){
                    for(int i = 1;i<=paramsNum;i++){
                        pre.setString(i,RandomUtil.getRandomString(minLen));
                    }
                    pre.addBatch();
                }
                pre.executeBatch();
                conn.commit();
                logger.info("batch insert nums = "+nums+",sql = "+sb.toString());
            }

        } catch (SQLException e) {
            logger.error(" execute error : sql = "+sb.toString(),e);
        }finally {
            HikariCPPoolUtil.closePreparedStatement(pre);
            HikariCPPoolUtil.closeConnection(conn);
        }
    }

}
